今天增加側邊導航列,
這也算是普遍網頁需要的功能,
那麼就開始吧!
首先,要知道自己需要甚麼,
一般網頁,不太需要太多複雜機制?
或者 功能相當複雜的網頁(資料需要交錯使用之類的)?
如果沒特別複雜,就用個react-router-dom 解決導航問題,
但功能複雜可以考慮redux,
以及有無實際router需要是否要再多安裝react-router-dom。
這邊只是單純demo展示,所以僅使用react-router-dom,
(當然你想用useEffect自己增加事件處理邏輯...也是可以,但我不想)
後面元件突然想弄點特別的再斟酌安裝redux,
後面也會提醒一下如果導引使用純redux後,primereact元件可能會有甚麼問題。
npm i react-router-dom --save
然後調整一下頁面,給sidebar留一個位子,旁邊的內文加點RWD設計,
老實說,RWD對我來說一直是個很抽象的概念,但秉持使用方好點,
畫面一直維持滿版的就可以了吧(?
於是我這不專業的門外人就不多說甚麼太專業的話了
.sidebar {
width: 200px;
}
.content {
display: flex;
margin-left: 200px;
}
再來添加router
index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import './styles.scss';
import 'primereact/resources/themes/arya-green/theme.css';
import 'primereact/resources/primereact.css';
import 'primeicons/primeicons.css'
import App from './App';
import reportWebVitals from './reportWebVitals';
import {BrowserRouter} from 'react-router-dom';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
reportWebVitals();
※有些人會把Routers(Switch)跟 Router也寫在這裡,但我個人是喜歡寫成這樣,
我個人覺得沒有對錯(也可能我這是壞習慣,請大神們不吝指教)全憑個人
App.tsx
import React from 'react';
import { Sidebar } from 'primereact/sidebar';
import ButtonCompnent from './components/Buttons';
import FormsCompnent from './components/Forms';
import {Route, Routes, useNavigate, useLocation } from 'react-router-dom';
function App() {
const navigate = useNavigate();
const location = useLocation();
return (
<div className="App">
<Sidebar
className="sidebar"
visible={true}
position="left"
onHide={() => { }}
showCloseIcon={false}
modal={false}
dismissable={false}
header="PrimeReact二三事"
>
</Sidebar>
<div className="content">
<Routes>
<Route path='/buttons' Component={ButtonCompnent} />
<Route path='/forms' Component={FormsCompnent} />
</Routes>
</div>
</div>
);
}
export default App;
這版Sidebar預設是隱藏,當然你可以做一個RWD判定,如果視窗小於多少就隱藏之類的,
這部分就自由發揮,我讓她固定在左側,然後onHide我不寫出來就紅,所以寫一個空的,
在來看看她的右上角有個X的icon,本來就不打算能關就把它隱藏吧,
(利用showCloseIcon 將它隱藏),
如果在modal未設定情況下run start,就會發現content區域有一層灰灰的遮罩,
如果沒有需要,切記設定為false
※既然關閉了遮罩(modal),dismissable要記得關掉,
不然content區域在用到CheckBox之類的元件時,就會有驚天地泣鬼神的事情,
甚麼GROUP 選第一個之後,第二個沒辦法點之類的狗血事
再來添加PanelMenu
import { PanelMenu } from 'primereact/panelmenu';
import { MenuItem, MenuItemCommandEvent } from 'primereact/menuitem'; //ts定義引用
先來設定項目的部分
const [pitem,setPItem] =useState<string>(location.pathname);
const items: MenuItem[] = [
{
label: 'Button',
data: '/buttons',
icon:'pi pi-box',
className:pitem==='/buttons'?'p-highlight':'',
command: (e: MenuItemCommandEvent) =>{
setPItem(e.item.data);
navigate(e.item.data);
}
},
{
label: 'Forms',
data: '/forms',
icon:'pi pi-receipt',
className:pitem==='/forms'?'p-highlight':'',
command: (e: MenuItemCommandEvent) =>{
setPItem(e.item.data);
navigate(e.item.data);
}
}
]
然後在sidebar內使用它
<Sidebar
className="sidebar"
visible={true}
position="left"
onHide={() => {}}
showCloseIcon={false}
modal={false}
dismissable={true}
header="PrimeReact二三事"
>
<PanelMenu model={items} />
</Sidebar>
再來因為個人覺得原始樣式不好看,隨變魔改一下它的樣式,
當然你也可以用template整個大改,但我覺得不是這次主題就不大動干戈
.sidebar {
width: 200px;
.p-sidebar-header {
font-size: 20px;
font-weight: bold;
}
.p-sidebar-content {
padding: 0;
.p-panelmenu {
.p-panelmenu-panel {
&.p-highlight {
.p-panelmenu-header-content {
background-color: #303030;
}
}
&:hover{
.p-panelmenu-header-content {
background-color: #424242;
}
}
.p-panelmenu-header {
.p-panelmenu-header-content {
border: 0;
border-radius: 0;
}
}
}
}
}
}
好了,一個簡單的導覽列就完成啦,讓我們來看看成果
勉強還算可以吧?
總之頂用!
明天就可以開始繼續進行預計要動的Forms囉~
[題外話]
如果我再設定panelmenu切換頁面邏輯時,單純使用redux dispatch 當前item 點及項目時,
要特別注意,建議是在item內增加 url:'#'設定...
為什麼呢?
因為如果不加,會發現你在切item的時候,
其它能展開的PrimeReact元件(例如DropDown Calendar...),
收、不、起、乃
只好硬著頭皮去硬嗑它元件邏輯,發現...
好樣的!!!
在沒有url情況下,
它會阻止事件冒泡,冒不到外層就沒辦法觸發收合事件,
但也不能說是bug,因為也許有些人就是不希望收起來阿~~~
好了,今天就到此為止啦~~
明天見!